package com.adee.design.action.promise;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class MyPromise<T> implements IPromise{
    private Lock lock;
    private Condition condition;
    private AtomicBoolean done = new AtomicBoolean(false);
    private T data;

    {
        lock = new ReentrantLock();
        condition = lock.newCondition();
    }

    @Override
    public Result<T> get() {
        lock.lock();
        Result<T> result = new Result<>();
        try {
            // 不能用if，用while防止虚假唤醒
            while(!done.get()) {
                condition.await();
            }
            result.setData(data);
            return result;
        } catch (Exception e) {
            result.setT(e);
            return result;
        } finally {
            lock.unlock();
        }
    }

    @Override
    public boolean complete() {
        return false;
    }

    public Lock getLock() {
        return lock;
    }

    public void setLock(Lock lock) {
        this.lock = lock;
    }

    public Condition getCondition() {
        return condition;
    }

    public void setCondition(Condition condition) {
        this.condition = condition;
    }

    public AtomicBoolean getDone() {
        return done;
    }

    public void setDone(AtomicBoolean done) {
        this.done = done;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }


    public static class Result<K> {
        public K getData() {
            return data;
        }

        public void setData(K data) {
            this.data = data;
        }

        public Throwable getT() {
            return t;
        }

        public void setT(Throwable t) {
            this.t = t;
        }

        private K data;
        private Throwable t;
    }
}
